/*
 * psapp.cpp
 *
 *  Created on: 2011-5-17
 *      Author: chenl
 */

#include "psapp.h"
#include "common/common_err.h"
#include "ps_error.h"
#include "processmgt.h"
#include "scheduler_o_n.h"
#include "scheduler_o_1.h"
#include "config.h"
#include <assert.h>

CPSApp::CPSApp() : logEngine(GET_PSTHREADLOG_INSTANCE()), pScheduler_(NULL), bIsModified_(false)
{

}

CPSApp::~CPSApp()
{

}

int32_t CPSApp::Initialize()
{
	int32_t ret = pthread_mutex_init(&mutex_,NULL);
	if (0 > ret)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "pthread_mutex_init failed! ret=%d", ret);
		return E_INIT_MUTEX_FAIL;
	}

	ret = InitScheduler();
	if (0 > ret)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "pthread_mutex_init failed! ret=%d", ret);
		return E_PS_INIT_SCHED_FAIL;
	}

	return S_OK;
}

int32_t CPSApp::Uninitialize()
{
	pthread_mutex_destroy(&mutex_);
	DelScheduler();
	return S_OK;
}

int32_t CPSApp::InitScheduler()
{
	if (NULL != pScheduler_)
	{
		DelScheduler();
	}
	int32_t ret = S_OK;
	CParamConfig& paramConfig = GET_PARAMCONFIG_INSTANCE();
	switch (paramConfig.GetScheduler())
	{
	case enmScheduler_O_N:
		logEngine.WriteLog(enmLogLevel_INFO, "Init scheduler %d", paramConfig.GetScheduler());
		pScheduler_ = new CScheduler_O_N();
		if (NULL == pScheduler_)
		{
			logEngine.WriteLog(enmLogLevel_FATAL, "Init scheduler %d failed because we are out of memory", paramConfig.GetScheduler());
			ret = E_MEMALLOC_FAIL;
		}
		break;
	case enmScheduler_O_1:
		logEngine.WriteLog(enmLogLevel_INFO, "Init scheduler %d", paramConfig.GetScheduler());
		pScheduler_ = new CScheduler_O_1();
		break;
	case enmScheduler_BFS:
		logEngine.WriteLog(enmLogLevel_INFO, "Init scheduler %d", paramConfig.GetScheduler());
//		break;
	case enmScheduler_CFS:
		logEngine.WriteLog(enmLogLevel_INFO, "Init scheduler %d", paramConfig.GetScheduler());
//		break;
	default:
		logEngine.WriteLog(enmLogLevel_FATAL, "Init unimplemented or undefined scheduler %d", paramConfig.GetScheduler());
		ret = E_PS_MISCONFIGED;
	}
	return ret;
}

int32_t CPSApp::DelScheduler()
{
	delete pScheduler_;
	return S_OK;
}

void CPSApp::DoSchedule()
{
	if (NULL == pScheduler_)
	{
		int32_t ret = S_OK;
		ret = InitScheduler();
		if (0 > ret)
		{
			logEngine.WriteLog(enmLogLevel_FATAL, "Init scheduler failed! ret=0x%08x", ret);
			return;
		}
	}
	assert(NULL != pScheduler_);
	pScheduler_->schedule();
}
